<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	<title>Marvin JS Examples - Convert Structure To Image</title>
	<link type="text/css" rel="stylesheet" href="../js/lib/rainbow/github.css" />
	<link type="text/css" rel="stylesheet" href="../css/doc.css" />
	<script src="../js/lib/jquery-1.9.1.min.js"></script>
	<script src="../js/lib/rainbow/rainbow-custom.min.js"></script>
	<script src="../gui/lib/promise-1.0.0.min.js"></script>
	<script src="../js/marvinjslauncher.js"></script>
	<script src="../js/webservices.js"></script>
	<style>
	iframe#marvinjs-iframe {
		width: 0;
		height: 0;
		display: initial;
		position: absolute;
		left: -1000;
		top: -1000;
		margin: 0;
		padding: 0;
	}
	div.control {
		background-color: dark-grey;
	}
	
	div.control>input[type="button"] {
		margin: 0.5em;
	}
	
	.formats>input[type="radio"] {
		margin: 0.2em;
	}
	</style>
	<script>
		var source = '<cml><MDocument><MChemicalStruct><molecule molID="m1"><atomArray><atom id="a1" elementType="O" x2="-3.75" y2="1.6015625" lonePair="2"/><atom id="a2" elementType="C" x2="-2.218436281132859" y2="1.4405886665678136"/><atom id="a3" elementType="Cl" x2="-1.8982522772735098" y2="-0.06575863856224728" lonePair="3"/><atom id="a4" elementType="C" x2="-1.3132469926024501" y2="2.686474837905233"/></atomArray><bondArray><bond atomRefs2="a1 a2" order="1" id="b1"/><bond atomRefs2="a2 a3" order="1" id="b2"/><bond atomRefs2="a2 a4" order="1" id="b3"><bondStereo>W</bondStereo></bond></bondArray></molecule></MChemicalStruct><MElectronContainer occupation="0 0" radical="0" id="o1"><MElectron atomRefs="m1.a1" difLoc="0.0 0.0 0.0"/><MElectron atomRefs="m1.a1" difLoc="0.0 0.0 0.0"/></MElectronContainer><MElectronContainer occupation="0 0" radical="0" id="o2"><MElectron atomRefs="m1.a1" difLoc="0.0 0.0 0.0"/><MElectron atomRefs="m1.a1" difLoc="0.0 0.0 0.0"/></MElectronContainer><MElectronContainer occupation="0 0" radical="0" id="o3"><MElectron atomRefs="m1.a3" difLoc="0.0 0.0 0.0"/><MElectron atomRefs="m1.a3" difLoc="0.0 0.0 0.0"/></MElectronContainer><MElectronContainer occupation="0 0" radical="0" id="o4"><MElectron atomRefs="m1.a3" difLoc="0.0 0.0 0.0"/><MElectron atomRefs="m1.a3" difLoc="0.0 0.0 0.0"/></MElectronContainer><MElectronContainer occupation="0 0" radical="0" id="o5"><MElectron atomRefs="m1.a3" difLoc="0.0 0.0 0.0"/><MElectron atomRefs="m1.a3" difLoc="0.0 0.0 0.0"/></MElectronContainer></MDocument></cml>';
		var marvin;
		
		$(document).ready(function handleDocumentReady (e) {
			// load marvin namespace in a separate frame to avoid css conflict
			// the display attribute of this iframe cannot be "none", but you can hide it somewhere
			$('body').append($('<iframe>', { id: "marvinjs-iframe", src: "../marvinpack.html"}));
			// wait for the reference of marvin namespace from the iframe
			MarvinJSUtil.getPackage("#marvinjs-iframe").then(function(marvinNameSpace) {
				// the reference to the namespace is arrived but there is no guaranty that its initalization has been finished
				// because of it, wait till the ready state to be sure the whole API is available
				marvinNameSpace.onReady(function() {
					marvin = marvinNameSpace;
					initControl();
				});	
			}, function(error) {
				alert("Cannot retrieve marvin instance from iframe:"+error);
			});
		});
		
		function initControl() {
			$("#molsource-box").val(source);
			$("#createPNG").on("click", function() {
				createImage("image/png", applyDataUri);
			});
			$("#createJPEG").on("click", function() {
				createImage("image/jpeg", applyDataUri);
			});
			$("#createSVG").on("click", function() {
				createImage("image/svg", applySvg);
			});
		}
		
		function createImage(imageType, callback) {
			var exporter = createExporter(imageType);
			exporter.render($("#molsource-box").val()).then(callback, alert);
		}
		
		function applySvg(svg) {
			$("#imageContainer").html(svg);
			$("#imageContainer").css("display", "inline-block");
		}
		
		function applyDataUri(dataUri) {
			$('#imageContainer').empty();
			var img = $('<img>', { src: dataUri}).appendTo($("#imageContainer"));
			$("#imageContainer").css("display", "inline-block");
		}
		
		function createExporter(imageType) {
			var settings = {
				'carbonLabelVisible' : $("#chbx-carbonVis").is(':checked'),
				'cpkColoring' : $("#chbx-coloring").is(':checked'),
				'chiralFlagVisible': $("#chbx-chiral").is(':checked'),
				'atomIndicesVisible': $("#chbx-atomIndeces").is(':checked'),
				'implicitHydrogen' : $("#implicittype").val(),
				'displayMode' : $("#displayMode").val(),
				'background-color': $('#bg').val(),
				'zoomMode' : $("#zoommode").val(),
				'width' : parseInt($("#w").val(), 10),
				'height' : parseInt($("#h").val(), 10)
			};

			var inputFormat = $("input[type='radio'][name='inputFormat']:checked").val();
			if(inputFormat == "") {
				inputFormat = null;
			}
			var defaultServices = getDefaultServices();
			var services = {};
			services['molconvertws'] = defaultServices['molconvertws'];
			if($('#chbx-calcStereo').is(":checked")) {
				services['stereoinfows'] = defaultServices['stereoinfows']; // enable stereo calculation
			}
			var params = {
					'imageType': imageType, // type of output image
					'settings': settings, // display settings
					'inputFormat': inputFormat, // renderer will expect molecule source in this format
					'services': services // to resolve any molecule format and be able to calculate stereo info
			}
			return new marvin.ImageExporter(params);
		}
	</script>
</head>
<body>
	<h1>Marvin JS Examples - Convert Structure To Image</h1>
	<div style="clear: both; width: 100%; text-align: right;"><a href="index.html">Back to index</a></div>
	<p>In this example, you can create PNG, JPEG or SVG picture from the given molecule source.</p>
	<noscript>
		<div>
			<p>Your web browser must have JavaScript enabled in order for this application to display correctly.</p>
		</div>
	</noscript>
	<div id="convertStructureInputHeader" class="table-layout">
		<li><span>Carbon labels</span><input type="checkbox" id="chbx-carbonVis" /></li>
		<li><span>CPK coloring</span><input type="checkbox" id="chbx-coloring" checked="checked" /></li>
		<li><span>Show Stereo Info</span><input type="checkbox" id="chbx-calcStereo" checked="checked"/></li>
		<li><span>Show chiral flag</span><input type="checkbox" id="chbx-chiral" checked="checked" /></li>
		<li><span>Atom Indeces</span><input type="checkbox" id="chbx-atomIndeces" /></li>
		<li><span>Implicit Hydrogens</span>
			<select id="implicittype" name="unittype">
				<option value="ALL">ALL</option>
				<option value="OFF">OFF</option>
				<option value="HETERO">HETERO</option>
				<option value="TERMINAL_AND_HETERO" selected>TERMINAL_AND_HETERO</option>
			</select>
		</li>
		<li><span>Display Mode</span>
			<select id="displayMode" name="unittype">
				<option value="WIREFRAME" selected>wireframe</option>
				<option value="BALLSTICK">ball and stick</option>
			</select>
		</li>
		<li><span>Zoom Mode</span>
			<select id="zoommode" name="unittype">
				<option value="fit">fit</option>
				<option value="autoshrink">autoshrink</option>
			</select>
		</li>
		<li><span>Width:</span><input id="w" type="number" name="quantity" min="1"
			value="300" /></li>
		<li><span>Height:</span><input id="h" type="number" name="quantity" min="1"
			value="300" /></li>
		<li><span>Background Color:</span><input id="bg" type="color" name="bg" value="#ffffff"/></li>
		<div class="control">
			<input id="createPNG" type="button" value="Create PNG"/>
			<input id="createJPEG" type="button" value="Create JPEG"/>
			<input id="createSVG" type="button" value="Create SVG"/>
		</div>
	</div>
	<div>
	<div class="formats">
	<input type="radio" name="inputFormat" value="">AUTO</input>
	<input type="radio" name="inputFormat" value="mol">mol</input>
	<input type="radio" name="inputFormat" value="mrv" checked>mrv</input>
	<input type="radio" name="inputFormat" value="smiles">smiles</input>
	<input type="radio" name="inputFormat" value="smarts">smarts</input>
	</div>
	<textarea id="molsource-box"></textarea>
	</div>
	<div id="imageContainer" class="left10" style="display: none;">
		<img id="image" class="bordered" />
	</div>
	<div>
	<p>Create a DIV element where the generated images will be embedded. It is hidden till the image is inserted.
		<pre><code data-language="html">&lt;div id=&quot;imageContainer&quot; class=&quot;left10&quot; style=&quot;display: none;&quot;&gt;
  &lt;img id=&quot;image&quot; class=&quot;bordered&quot; /&gt;
&lt;/div&gt;</code></pre></p>
	<p>The following dependencies are used in this example: 
		<ul>
			<li><strong>jquery-1.9.1.min.js</strong> - The example is written in JQuery but the ImageExporter API does not require it.</li>
			<li><strong>promise-1.0.0.min.js</strong> - Promise overlay (required if the current browser does not provide a Promise implementation).</li>
			<li><strong>marvinjslauncher.js</strong> - The MarvinJSUtil is a helper API to get the <code>marvin</code> object from the iframe.</li>
			<li><strong>webservices.js</strong> - Defines the <code>getDefaultServices</code> function that provides the settings of the expected services.</li>
		</ul></p>
		<pre><code data-language="javascript">	&lt;script src="../js/lib/jquery-1.9.1.min.js"&gt;&lt;/script&gt;
	&lt;script src="../gui/lib/promise-1.0.0.min.js"&gt;&lt;/script&gt;
	&lt;script src="../js/marvinjslauncher.js"&gt;&lt;/script&gt;	
	&lt;script src="../js/webservices.js"&gt;&lt;/script&gt;</code></pre>
		<p>You need the <em>marvin.ImageExporter</em> class to convert structure to image. Loads this API into a separate iframe to avoid potential css conflicts.</p>
		Use the <strong>marvinpack.html</strong> that loads the <em>marvin</em> namespace.
		
		<pre><code data-language="javascript">		$(document).ready(function handleDocumentReady (e) {
			// load marvin namespace in a separate frame to avoid css conflict
			// the display attribute of this iframe cannot be "none", but you can hide it somewhere
			$('body').append($('&lt;iframe&gt;', { id: "marvinjs-iframe", src: "../marvinpack.html"}));
			// wait for the reference of marvin namespace from the iframe
			MarvinJSUtil.getPackage("#marvinjs-iframe").then(function(marvinNameSpace) {
				// the reference to the namespace is arrived but there is no guaranty that its initalization has been finished
				// because of it, wait till the ready state to be sure the whole API is available
				marvinNameSpace.onReady(function() {
					marvin = marvinNameSpace;
					initControl();
				});	
			}, function(error) {
				alert("Cannot retrieve marvin instance from iframe:"+error);
			});
		});
</code></pre></p>
	<p>To hide the iframe, the following CSS settings are used:</p>
	<pre><code data-language="stylesheet">	iframe#marvinjs-iframe {
		width: 0;
		height: 0;
		display: initial;
		position: absolute;
		left: -1000;
		top: -1000;
		margin: 0;
		padding: 0;
	}</code></pre>
	<p>The <code>initcontrol</code> function bind click handler for the buttons.</p>
	<pre><code data-language="javascript">		function initControl() {
			$("#molsource-box").val(source);
			$("#createPNG").on("click", function() {
				createImage("image/png", applyDataUri);
			});
			$("#createJPEG").on("click", function() {
				createImage("image/jpeg", applyDataUri);
			});
			$("#createSVG").on("click", function() {
				createImage("image/svg", applySvg);
			});
		}</code></pre>
	<p>The <code>createImage</code> function creates a new instance of ImageExporter class and call its render function to convert the given string to image.
	It is an asynchrone exporter, the <code>render</code> function returns with a <code>Promise</code> instance. The given <code>callback</code> function processes the result of the image export. It is automatically evaluated when the export process is completed.</p>
	<pre><code data-language="javascript">		function createImage(imageType, callback) {
			var exporter = createExporter(imageType);
			exporter.render($("#molsource-box").val()).then(callback, alert);
		}</code></pre>
	<p>The <code>createExporter</code> function retrieves the current settings to create a new ImageExporter object with these settings.</p>
	<pre><code data-language="javascript">		function createExporter(imageType) {
			var settings = {
				'carbonLabelVisible' : $("#chbx-carbonVis").is(':checked'),
				'cpkColoring' : $("#chbx-coloring").is(':checked'),
				'chiralFlagVisible': $("#chbx-chiral").is(':checked'),
				'atomIndicesVisible': $("#chbx-atomIndeces").is(':checked'),
				'implicitHydrogen' : $("#implicittype").val(),
				'displayMode' : $("#displayMode").val(),
				'background-color': $('#bg').val(),
				'zoomMode' : $("#zoommode").val(),
				'width' : parseInt($("#w").val(), 10),
				'height' : parseInt($("#h").val(), 10)
			};

			var inputFormat = $("input[type='radio'][name='inputFormat']:checked").val();
			if(inputFormat == "") {
				inputFormat = null;
			}
			var defaultServices = getDefaultServices();
			var services = {};
			services['molconvertws'] = defaultServices['molconvertws'];
			if($('#chbx-calcStereo').is(":checked")) {
				services['stereoinfows'] = defaultServices['stereoinfows']; // enable stereo calculation
			}
			var params = {
					'imageType': imageType, // type of output image
					'settings': settings, // display settings
					'inputFormat': inputFormat, // renderer will expect molecule source in this format
					'services': services // to resolve any molecule format and be able to calculate stereo info
			}
			return new marvin.ImageExporter(params);
		}</code></pre>
		<p>At PNG and JPEG image generation, ImageExporter generates a base64 based data URI. To display it, create a new <code>img</code> tag and set the result string to its <code>src</code> attribute.</p>
		<pre><code data-language="javascript">		function applyDataUri(dataUri) {
			$('#imageContainer').empty();
			var img = $('<img>', { src: dataUri}).appendTo($("#imageContainer"));
			$("#imageContainer").css("display", "inline-block");
		}</code></pre>
		<p>At SVG export, ImageExporter generates a serialized SVG tag that includes a scalable vector graphics. To display it, insert the result as raw data into an empty DOM element.</p>
		<pre><code data-language="javascript">		function applySvg(svg) {
			$("#imageContainer").html(svg);
			$("#imageContainer").css("display", "inline-block");
		}</code></pre>
	</div>
	<div style="clear: both; width: 100%; text-align: right;"><a href="index.html">Back to index</a></div>
</body>
</html>
